package org.wk.upms.service;

import com.google.common.base.Strings;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wk.core.common.exception.ExceptionCode;
import org.wk.core.common.tool.RegexUtils;
import org.wk.core.common.view.PageVo;
import org.wk.core.common.view.ResponseVo;
import org.wk.core.web.exception.GeneralException;
import org.wk.upms.dao.ManagerDao;
import org.wk.upms.dao.ManagerRoleDao;
import org.wk.upms.domain.ManagerEntity;
import org.wk.upms.domain.ManagerRoleEntity;
import org.wk.upms.shiro.ShiroUtils;
import org.wk.upms.view.ManagerVo;


import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Transactional(rollbackFor = Exception.class)
@Service
public class ManagerServiceImpl implements ManagerService {

    @Autowired
    private ManagerDao managerDao;

    @Autowired
    private ManagerRoleDao managerRoleDao;

    /**
     * 通过用户ID 查询该用户拥有的所有权限
     * @param userId 用户ID
     * @return
     */
    @Override
    public List<String> queryAllPerms(String userId) {
        return null;
    }

    @Override
    public ManagerVo selectByUserId(String userId) {
        return null;
    }

    @Override
    public ManagerVo selectByMobile(String mobile) {
        ManagerEntity managerEntity = managerDao.findByMobile(mobile);
        if (managerEntity==null)
            return null;

        ManagerVo managerVo = new ManagerVo();
        BeanUtils.copyProperties(managerEntity, managerVo);
        managerVo.setUserId(managerEntity.getId());
        return managerVo;
    }

    /**
     * 分页查询人员列表
     *
     * @param params
     * @return
     */
    @Override
    public PageVo queryPage(Map<String, Object> params) {
        String realName = (String)params.get("realName");
        String temp = (String)params.get("page");
        Integer pageNo = temp==null?0:Integer.parseInt(temp)-1;
        temp = (String) params.get("limit");
        Integer pageSize = temp==null?10:Integer.parseInt(temp);
        //Page<ManagerEntity> page = managerDao.findAll(PageRequest.of(pageNo,pageSize,new Sort(Sort.Direction.ASC,"createTime")));
        Page<ManagerEntity> page = managerDao.findAll(new Specification<ManagerEntity>() {
            @Override
            public Predicate toPredicate(Root<ManagerEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if(!Strings.isNullOrEmpty(realName)){
                    list.add(criteriaBuilder.like(root.get("realName").as(String.class), "%"+realName+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, PageRequest.of(pageNo,pageSize,new Sort(Sort.Direction.DESC,"createTime")));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<ManagerVo> managerVos = new ArrayList<>();
        for(ManagerEntity managerEntity : page.getContent()){
            ManagerVo managerVo = new ManagerVo();
            BeanUtils.copyProperties(managerEntity,managerVo);
            managerVo.setUserId(managerEntity.getId());
            managerVo.setCreateTime(sdf.format(managerEntity.getCreateTime()));
            managerVos.add(managerVo);
        }
        PageVo pageVo = new PageVo<ManagerVo>();
        pageVo.setTotal(page.getTotalElements());
        pageVo.setPageNo(++pageNo);
        pageVo.setPageSize(pageSize);
        pageVo.setResult(managerVos);
        pageVo.setTotalPages(page.getTotalPages());
        return pageVo;
    }

    @Override
    public ResponseVo updatePassword(String userId, String password, String newPassword) {
        Optional<ManagerEntity> optional = managerDao.findById(userId);
        if (!optional.isPresent()) {
            throw new GeneralException();
        }
        ManagerEntity managerEntity = optional.get();
        if (!password.equals(managerEntity.getPassword())){
            return ResponseVo.error("原密码不正确");
        }
        String salt = RandomStringUtils.randomAlphanumeric(20);
        managerEntity.setSalt(salt);
        managerEntity.setPassword(ShiroUtils.sha256(newPassword, salt));
        managerDao.update(managerEntity);
        return ResponseVo.success();
    }

    @Override
    public ManagerVo selectById(String userId) {
        Optional<ManagerEntity> optional = managerDao.findById(userId);
        if (!optional.isPresent())
            return null;
        ManagerEntity managerEntity = optional.get();
        ManagerVo managerVo = new ManagerVo();
        BeanUtils.copyProperties(managerEntity, managerVo,"salt","password");
        managerVo.setUserId(managerEntity.getId());
        return managerVo;
    }

    @Override
    public void save(ManagerVo user) {
        verifyForm(user);
        ManagerEntity managerEntity = new ManagerEntity();
        BeanUtils.copyProperties(user,managerEntity);
        String salt = RandomStringUtils.randomAlphanumeric(20);
        managerEntity.setSalt(salt);
        managerEntity.setPassword(ShiroUtils.sha256(managerEntity.getPassword(), managerEntity.getSalt()));
        managerEntity =  managerDao.save(managerEntity);
        String userId = managerEntity.getId();
        List<String> roleIds = user.getRoleIds();
        //处理用户角色管理
        List<ManagerRoleEntity> managerRoleEntities = new ArrayList<>();
        for (String roleId :roleIds) {
            ManagerRoleEntity managerRoleEntity = new ManagerRoleEntity();
            managerRoleEntity.setManagerId(userId);
            managerRoleEntity.setRoleId(roleId);
            managerRoleEntities.add(managerRoleEntity);
        }
        managerRoleDao.saveBatch(managerRoleEntities);

    }


    @Transactional
    @Override
    public void update(ManagerVo user) {
        String userId = user.getUserId();
        if (Strings.isNullOrEmpty(userId)) {
            throw new GeneralException();
        }
        Optional<ManagerEntity> optional = managerDao.findById(userId);
        if (!optional.isPresent()) {
            throw new GeneralException();
        }
        ManagerEntity managerEntity = optional.get();

        String pwd = user.getPassword();
        if (!Strings.isNullOrEmpty(pwd)) {
            String salt = RandomStringUtils.randomAlphanumeric(20);
            managerEntity.setSalt(salt);
            managerEntity.setPassword(ShiroUtils.sha256(pwd, salt));
        }
        if (!Strings.isNullOrEmpty(user.getRealName())) {
            managerEntity.setRealName(user.getRealName());
        }
        if (!Strings.isNullOrEmpty(user.getDeptId())) {
            managerEntity.setDeptId(user.getDeptId());
            managerEntity.setDeptName(user.getDeptName());
        }
        if (!Strings.isNullOrEmpty(user.getStatus())) {
            managerEntity.setStatus(user.getStatus());
        }
        if (!Strings.isNullOrEmpty(user.getMobile())) {
            managerEntity.setMobile(user.getMobile());
        }
        if (!Strings.isNullOrEmpty(user.getEmail())) {
            managerEntity.setEmail(user.getEmail());
        }

        managerDao.update(managerEntity);

        List<String> roleIds = user.getRoleIds();
        if (roleIds!=null && !roleIds.isEmpty()) {
            managerRoleDao.deleteByManagerId(userId);
            //处理用户角色管理
            List<ManagerRoleEntity> managerRoleEntities = new ArrayList<>();
            for (String roleId :roleIds) {
                ManagerRoleEntity managerRoleEntity = new ManagerRoleEntity();
                managerRoleEntity.setManagerId(userId);
                managerRoleEntity.setRoleId(roleId);
                managerRoleEntities.add(managerRoleEntity);
            }
            managerRoleDao.saveBatch(managerRoleEntities);
        }
    }

    @Override
    public void deleteBatchIds(List<String> userIds) {

        managerDao.deleteByIdIn(userIds);
        managerRoleDao.deleteByManagerIdIn(userIds);
    }

    private void verifyForm(ManagerVo user){
        if(Strings.isNullOrEmpty(user.getMobile())){
            throw new GeneralException(ExceptionCode.ex_base_002);
        }
        ManagerEntity managerEntity = managerDao.findByMobile(user.getMobile());
        if (null != managerEntity){
            throw new GeneralException(ExceptionCode.ex_user_001);
        }
        if(!RegexUtils.checkMobileNum(user.getMobile())){
            throw new GeneralException(ExceptionCode.ex_base_004);
        }

    }
}
